package deep8jvmdvm;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
读写锁（ReentrantReadWriteLock）

在常见的开发中，我们经常会定义一个线程间共享的用作缓存的数据结构，比如一个较大的 Map。缓存中保存了全部的城市 Id 和城市 name 对应关系。这个大 Map 绝大部分时间提供读服务（根据城市 Id 查询城市名称等）。而写操作占有的时间很少，通常是在服务启动时初始化，然后可以每隔一定时间再刷新缓存的数据。但是写操作开始到结束之间，不能再有其他读操作进来，并且写操作完成之后的更新数据需要对后续的读操作可见。



在没有读写锁支持的时候，如果想要完成上述工作就需要使用 Java 的等待通知机制，就是当写操作开始时，所有晚于写操作的读操作均会进入等待状态，只有写操作完成并进行通知之后，所有等待的读操作才能继续执行。这样做的目的是使读操作能读取到正确的数据，不会出现脏读。



但是如果使用 concurrent 包中的读写锁（ReentrantReadWriteLock）实现上述功能，就只需要在读操作时获取读锁，写操作时获取写锁即可。当写锁被获取到时，后续的读写锁都会被阻塞，写锁释放之后，所有操作继续执行，这种编程方式相对于使用等待通知机制的实现方式而言，变得简单明了。



接下来，我们看下读写锁（ReentrantReadWriteLock）如何使用：

 */
public class TestReentrantReadWriteLock1 {

    public static void main(String[] args) {
        //1. 创建读写锁对象：
        ReadWriteLock rwLock = new ReentrantReadWriteLock();

        //2. 通过读写锁对象分别获取读锁（ReadLock）和写锁（WriteLock）：
        ReentrantReadWriteLock.ReadLock readLock = (ReentrantReadWriteLock.ReadLock) rwLock.readLock();
        ReentrantReadWriteLock.WriteLock writeLock = (ReentrantReadWriteLock.WriteLock) rwLock.writeLock();

        //3. 使用读锁（ReadLock）同步缓存的读操作，使用写锁（WriteLock）同步缓存的写操作：

        //读操作
        readLock.lock();

        try {
            //从缓存中读取数据

        } finally {

        }


        //写操作
        writeLock.lock();
        try {
            //向缓存中写数据

        } finally {
            writeLock.unlock();
        }


    }
}

